package com.mrx.commons.gateway.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.net.InetSocketAddress;
import java.net.ProxySelector;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author Mr.X
 * @since 2024/12/2 18:36
 */
@RestController
@RequestMapping("/forward")
public class GoogleTranslateController {

    private static final String API = "https://translate.googleapis.com";

    private static final Logger logger = LoggerFactory.getLogger(GoogleTranslateController.class);

    private static final Set<String> HEADER_BLACK_LIST = Set.of("host", "connection", "content-length");

    private static final HttpClient client = HttpClient.newBuilder()
            .proxy(ProxySelector.of(new InetSocketAddress("127.0.0.1", 7897)))
            .build();

    @RequestMapping("/translate/**")
    public ResponseEntity<?> translate(
            @RequestHeader HttpHeaders headers, @RequestBody(required = false) String body,
            HttpServletRequest request
    ) throws Exception {
        String upstreamURL = API + request.getRequestURI().replace("/forward/translate", "");
        logger.info("upstreamURL: {}", upstreamURL);
        logger.info("upstreamBody: {}", body);
        HttpRequest.Builder builder = HttpRequest.newBuilder()
                .method(request.getMethod(), body == null ? HttpRequest.BodyPublishers.noBody() : HttpRequest.BodyPublishers.ofString(body))
                .uri(URI.create(upstreamURL));
        Map<String, String> requestHeaders = headers.toSingleValueMap().entrySet().stream()
                .filter(it -> HEADER_BLACK_LIST.stream().noneMatch(item -> item.equalsIgnoreCase(it.getKey())))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        logger.info("requestHeaders: {}", requestHeaders);
        requestHeaders.forEach(builder::header);
        HttpRequest upstreamRequest = builder.build();
        logger.info("upstreamRequest: {}", upstreamRequest);
        HttpResponse<byte[]> response = client.send(upstreamRequest, HttpResponse.BodyHandlers.ofByteArray());
        return ResponseEntity.status(response.statusCode())
                .body(response.body());
    }

}
